﻿using System;
using System.Collections.Generic;
using System.Text;

namespace libaklys {
namespace Protocol {
	public enum Direction {
		DIR_W,
		DIR_NW,
		DIR_N,
		DIR_NE,
		DIR_E,
		DIR_SE,
		DIR_S,
		DIR_SW,
		DIR_UP,
		DIR_DOWN,
		DIR_SELF,
		DIR_NONE = -1
	}
	public enum GameMode {
		MODE_NORMAL,
		MODE_EXPLORE,
		MODE_WIZARD
	}
	public enum GameStatus {
		LS_SAVED,
		LS_DONE,
		LS_IN_PROGRESS,
		LS_INVALID = -1,
		LS_CRASHED = -2
	}
	public enum EndClass {
		DIED,
		CHOKING,
		POISONING,
		STARVING,
		DROWNING,
		BURNING,
		DISSOLVED,
		CRUSHING,
		STONING,
		TURNED_SLIME,
		GENOCIDED,
		PANICKED,
		TRICKED,
		QUIT,
		ESCAPED,
		ASCENDED
	}
	public enum MenuRole {
		MI_TEXT,
		MI_NORMAL,
		MI_HEADING
	}
	public enum PlacementHint {
		PLHINT_ANYWHERE,
		PLHINT_LEFT,
		PLHINT_RIGHT,
		PLHINT_URGENT,
		PLHINT_INFO,
		PLHINT_ONELINER,
		PLHINT_CONTAINER,
		PLHINT_INVENTORY
	}

	public enum AuthStatus {
		NO_CONNECTION,
		AUTH_FAILED_UNKNOWN_USER,
		AUTH_FAILED_BAD_PASSWORD,
		AUTH_SUCCESS_NEW,
		AUTH_SUCCESS_RECONNECT
	}
	namespace Client {
		public class auth : register {
			public int ConnID { get; set; }
		}
	}
	namespace Server {
		public class auth : register {
		}
	}

	namespace Client {
		public class register {
			public string Email { get; set; }
			public string Username { get; set; }
			public string Password { get; set; }
		}
	}
	namespace Server {
		public class register {
			public int ConnID { get; set; }
			public AuthStatus Return { get; set; }
			public List<int> Version { get; set; }
			public string Game { get; set; }
		}
	}

	namespace Server {
		public class Statement {
			public Display Display { get; set; }
		}
		public class Query : Statement {
		}
		public class Response : Statement {
		}
	}
	namespace Client {
		public class Statement {
		}
		public class Query : Statement {
		}
		public class Response : Statement {
		}
	}

	public enum RestoreStatus {
		GAME_RESTORED,
		ERR_BAD_ARGS,
		ERR_BAD_FILE, //file isn't a saved game
		ERR_GAME_OVER, //this is the log of a completed game, play cannot be resumed
		ERR_IN_PROGRESS, //this game is active in a different process
		ERR_RESTORE_FAILED, //restoring the saved game state did not succeed, maybe try replaying the log instead
		ERR_REPLAY_FAILED //replaying the action log did not succeed
	}
	namespace Client {
		public class restore_game : Query {
			public int GameID { get; set; }
		}
	}
	namespace Server {
		public class restore_game : Response {
			public RestoreStatus Return { get; set; }
		}
	}

	namespace Client {
		public class set_email : Query {
			public string Email { get; set; }
		}
	}
	namespace Server {
		public class set_email : Response {
			public bool Return { get; set; }
		}
	}

	namespace Client {
		public class set_password : Query {
			public string Password { get; set; }
		}
	}
	namespace Server {
		public class set_password : Response {
			public bool Return { get; set; }
		}
	}

	namespace Client {
		public class describe_pos : Query {
			public bool Is_In { get; set; }
			public int X { get; set; }
			public int Y { get; set; }
		}
	}
	namespace Server {
		public class describe_pos : Response {
			public string BGDesc { get; set; }
			public string EffectDesc { get; set; }
			public string InvisDesc { get; set; }
			public string MonDesc { get; set; }
			public string ObjDesc { get; set; }
			public string TrapDesc { get; set; }
			public bool In { get; set; }
			public int ObjCount { get; set; }
		}
	}

	public enum ExitType {
		EXIT_REQUEST_SAVE,
		EXIT_FORCE_SAVE,
		EXIT_REQUEST_QUIT,
		EXIT_FORCE_QUIT,
		EXIT_PANIC
	}
	namespace Client {
		public class exit_game : Query {
			public ExitType Exit_Type { get; set; }
		}
	}
	namespace Server {
		public class exit_game : Response {
			public bool Return { get; set; }
		}
	}

	public enum ArgumentType {
		ARGS_NONE = 2,
		ARGS_DIRECTION = 4,
		ARGS_COORDINATES = 8,
		ARGS_INVENTORY = 16
	}
	public enum CommandResult {
		READY_FOR_INPUT,
		MULTI_IN_PROGRESS,
		OCCUPATION_IN_PROGRESS,
		POST_ACTION_DELAY,
		ERR_NO_INPUT_ALLOWED,
		ERR_COMMAND_FORBIDDEN, // tried to alter the game state while viewing a replay
		GAME_OVER, // i.e. player died
		GAME_SAVED,
		GAME_PANICKED, // something went wrong in libnethack and panic() was called
		ERR_FORCED_EXIT, // exit from the command loop was forced by a call to nh_exit_game
		ERR_GAME_NOT_RUNNING // possibilities: the init sequence was incorrect and the game is not running YET or some api call other than nh_do_move caused a panic, which killed the game or an attempt was made to call nh_do_move after some other final status (>= GAME_OVER) was returned
	}
	public class CommandArguments {
			public int ArgType { get; set; }
			public Direction D { get; set; }
			public char? InvLet { get; set; }
			public int? X { get; set; }
			public int? Y { get; set; }
	}
	namespace Client {
		public class game_command : Query {
			public CommandArguments Arg;
			public string Command { get; set; }
			public int Count { get; set; }
		}
	}
	namespace Server {
		public class game_command : Response {
			public CommandResult Return { get; set; }
		}
	}

	public class CommandDefinition {
		public string Name { get; set; }
		public string Desc { get; set; }
		public char Def { get; set; }
		public char Alt { get; set; }
		public int BitFlags { get; set; }
	}
	namespace Client {
		public class get_commands : Query {
		}
	}
	namespace Server {
		public class get_commands : Response {
			public List<CommandDefinition> CmdList { get; set; }
		}
	}

	public class Glyph {
		public string Name { get; set; }
		public char Character { get; set; }
		public int Colour { get; set; }
	}
	namespace Client {
		public class get_drawing_info : Query {
		}
	}
	namespace Server {
		public class get_drawing_info : Response {
			public int Feature_Offset { get; set; }
			public int Num_BGElements { get; set; }
			public List<Glyph> BGElements { get; set; }
			public int Num_Effects { get; set; }
			public List<Glyph> Effects { get; set; }
			public int Num_ExplTypes { get; set; }
			public List<Glyph> ExplSyms { get; set; }
			public List<Glyph> ExplTypes { get; set; }
			public List<Glyph> Invis { get; set; }
			public int Num_Monsters { get; set; }
			public List<Glyph> Monsters { get; set; }
			public int Num_Objects { get; set; }
			public List<Glyph> Objects { get; set; }
			public List<Glyph> SwallowSyms { get; set; }
			public int Num_Traps { get; set; }
			public List<Glyph> Traps { get; set; }
			public int Num_Warnings { get; set; }
			public List<Glyph> Warnings { get; set; }
			public int Num_ZapTypes { get; set; }
			public List<Glyph> ZapSyms { get; set; }
			public List<Glyph> ZapTypes { get; set; }
		}
	}

	namespace Client {
		public class get_obj_commands : Query {
			public char InvLet { get; set; }
		}
	}
	namespace Server {
		public class get_obj_commands : Response {
			public List<CommandDefinition> CmdList { get; set; }
		}
	}

	public enum OptionClass {
		CURRENT_BIRTH_OPTIONS,
		ACTIVE_BIRTH_OPTIONS,
		GAME_OPTIONS
	}
	public enum OptionType {
		OPTTYPE_BOOL,
		OPTTYPE_INT,
		OPTTYPE_ENUM,
		OPTTYPE_STRING,
		OPTTYPE_AUTOPICKUP_RULES
	}
	public enum AutopickupAction {
		AP_GRAB, AP_LEAVE
	}
	public enum Beatitude {
		B_UNKNOWN,
		B_BLESSED,
		B_UNCURSED,
		B_CURSED,
		B_DONT_CARE
	}
	public class AutopickupRule {
		public AutopickupAction Action { get; set; }
		public Beatitude BUC { get; set; }
		public int OClass { get; set; }
		public string Pattern { get; set; }
	}
	public class Option {
		public string Name { get; set; }
		public string HelpTxt { get; set; }
		public int? Min { get; set; }
		public int? Max { get; set; }
		public int? Length { get; set; }
		public List<string> Choices { get; set; }
		public List<string> RuleNames { get; set; }
		public OptionType Type { get; set; }
		public bool?  Value_Flag { get; set; }
		public int?   Value_Number { get; set; }
		public string Value_Choice { get; set; }
		public string Value_Text { get; set; }
		public List<AutopickupRule> Rules { get; set; }
	}
	namespace Client {
		public class get_options : Query {
			public OptionClass List { get; set; }
		}
	}
	namespace Server {
		public class get_options : Response {
			public List<Option> Options { get; set; }
		}
	}

	namespace Client {
		public class get_pl_prompt : Query {
			public int Align { get; set; }
			public int Gend { get; set; }
			public int Race { get; set; }
			public int Role { get; set; }
		}
	}
	namespace Server {
		public class get_pl_prompt : Response {
			public string Prompt { get; set; }
		}
	}

	namespace Client {
		public class get_root_pl_prompt : get_pl_prompt {
		}
	}
	namespace Server {
		public class get_root_pl_prompt : get_pl_prompt {
		}
	}

	namespace Client {
		public class get_roles : Query {
		}
	}
	namespace Server {
		public class get_roles : Response {
			public int Num_Aligns { get; set; }
			public int Def_Align { get; set; }
			public List<string> Alignnames { get; set; }
			public int Num_Genders { get; set; }
			public int Def_Gend { get; set; }
			public List<string> Gendnames { get; set; }
			public int Num_Races { get; set; }
			public int Def_Race { get; set; }
			public List<string> Racenames { get; set; }
			public int Num_Roles { get; set; }
			public int Def_Role { get; set; }
			public List<string> Rolenames_f { get; set; }
			public List<string> Rolenames_m { get; set; }
			public List<int> Matrix { get; set; }
		}
	}

	public class TopTenGame {
		public int BirthDate { get; set; }
		public string Death { get; set; }
		public int DeathDate { get; set; }
		public int Deaths { get; set; }
		public EndClass End_How { get; set; }
		public string EntryTxt { get; set; }
		public bool Highlight { get; set; }
		public int HP { get; set; }
		public int MaxHP { get; set; }
		public int MaxLvl { get; set; }
		public int Moves { get; set; }
		public string Name { get; set; }
		public string PlAlign { get; set; }
		public string PlGend { get; set; }
		public string PlRace { get; set; }
		public string PlRole { get; set; }
		public int Points { get; set; }
		public int Rank { get; set; }
		public int Ver_Major { get; set; }
		public int Ver_Minor { get; set; }
		public int PatchLevel { get; set; }
	}
	namespace Client {
		public class get_topten : Query {
			public string Player { get; set; }
			public int Top { get; set; }
			public int Around { get; set; }
			public bool Own { get; set; }
		}
	}
	namespace Server {
		public class get_topten : Response {
			public string Msg { get; set; }
			public List<TopTenGame> TopList { get; set; }
		}
	}

	public class ListGame {
		public string PlName { get; set; }
		public string Death { get; set; }
		public int? Depth { get; set; }
		public int GameID { get; set; }
		public bool? Has_Amulet { get; set; }
		public string Level_Desc { get; set; }
		public int? Moves { get; set; }
		public GameMode PlayMode { get; set; }
		public string PlAlign { get; set; }
		public string PlGend { get; set; }
		public string PlRace { get; set; }
		public string PlRole { get; set; }
		public GameStatus Status { get; set; }
	}
	namespace Client {
		public class list_games : Query {
			public int Limit { get; set; }
			public bool Completed { get; set; }
			public bool Show_All { get; set; }
		}
	}
	namespace Server {
		public class list_games : Response {
			public List<ListGame> Games { get; set; }
		}
	}

	namespace Client {
		public class shutdown : Query {
		}
	}
	namespace Server {
		public class shutdown : Response {
			public int Return { get; set; }
		}
	}

	namespace Client {
		public class start_game : Query {
			public string Name { get; set; }
			public int Alignment { get; set; }
			public int Gender { get; set; }
			public int Race { get; set; }
			public int Role { get; set; }
		}
	}
	namespace Server {
		public class start_game : Response {
			public int GameID { get; set; }
			public bool Return { get; set; }
		}
	}

	public class ViewInfo {
		public int Actions { get; set; }
		public int Max_Actions { get; set; }
		public int Max_Moves { get; set; }
		public int Moves { get; set; }
		public string NextCmd { get; set; }
	}
	public enum ViewAction {
		REPLAY_FORWARD,
		REPLAY_BACKWARD,
		REPLAY_GOTO
	}
	namespace Client {
		public class view_start : Query {
			public int GameID { get; set; }
		}
	}
	namespace Server {
		public class view_start : Response {
			public ViewInfo Info { get; set; }
			public bool Return { get; set; }
		}
	}

	namespace Client {
		public class view_step : Query {
			public ViewAction Action { get; set; }
			public int Count { get; set; }
			public ViewInfo Info { get; set; }
		}
	}
	namespace Server {
		public class view_step : view_start {
		}
	}

	namespace Client {
		public class view_finish : Query {
		}
	}
	namespace Server {
		public class view_finish : Response {
		}
	}

	/* ============ Server requests ============ */

	public enum MenuMode {
		PICK_NONE,
		PICK_ONE,
		PICK_ANY
	}
	public class MenuItem {
		public int ID { get; set; }
		public string Caption { get; set; }
		public MenuRole Role { get; set; }
		public bool Selected { get; set; }
		public char Accel { get; set; }
		public char Group_Accel { get; set; }
	}
	namespace Server {
		public class display_menu : Query {
			public string Title { get; set; }
			public PlacementHint PlHint { get; set; }
			public MenuMode How { get; set; }
			public List<MenuItem> Items { get; set; }
			public int ICount { get; set; }
		}
	}
	namespace Client {
		public class display_menu : Response {
			public List<int> Results { get; set; }
			public int Return { get; set; }
		}
	}

	public class ObjItem {
		public string Caption { get; set; }
		public int ID { get; set; }
		public MenuRole Role { get; set; }
		public int Count { get; set; }
		public int OType { get; set; }
		public int OClass { get; set; }
		public int Weight { get; set; }
		public Beatitude BUC { get; set; }
		public char Accel { get; set; }
		public char Group_Accel { get; set; }
		public bool Worn { get; set; }
	}
	public class PickStack {
		public int ID { get; set; }
		public int Count { get; set; }
	}
	namespace Server {
		public class display_objects : Query {
			public string Title { get; set; }
			public PlacementHint PlHint { get; set; }
			public MenuMode How { get; set; }
			public List<ObjItem> Items { get; set; }
			public int ICount { get; set; }
		}
	}
	namespace Client {
		public class display_objects : Response {
			public List<PickStack> Pick_List { get; set; }
			public int Return { get; set; }
		}
	}

	namespace Server {
		public class getdir : Query {
			public string Query { get; set; }
			public bool Restricted { get; set; }
		}
	}
	namespace Client {
		public class getdir : Response {
			public Direction Return { get; set; }
		}
	}

	namespace Server {
		public class getline : Query {
			public string Query { get; set; }
		}
	}
	namespace Client {
		public class getline : Response {
			public string Line { get; set; }
		}
	}

	public enum GetPosMode {
		SELECTED_DOT,
		SELECTED_COMMA,
		SELECTED_SEMICOLON,
		SELECTED_COLON,
		ABORTED = -1
	}
	namespace Server {
		public class getpos : Query {
			public bool Force { get; set; }
			public string Goal { get; set; }
			public int X { get; set; }
			public int Y { get; set; }
		}
	}
	namespace Client {
		public class getpos : Response {
			public GetPosMode Return { get; set; }
			public int X { get; set; }
			public int Y { get; set; }
		}
	}

	namespace Server {
		public class query_key : Query {
			public string Query { get; set; }
			public bool Allow_Count { get; set; }
		}
	}
	namespace Client {
		public class query_key : Response {
			public char Return { get; set; }
			public int? Count { get; set; }
		}
	}

	namespace Server {
		public class yn : Query {
			public string Query { get; set; }
			public char Def { get; set; }
			public string Set { get; set; }
		}
	}
	namespace Client {
		public class yn : Response {
			public char Return { get; set; }
		}
	}

	namespace Server {
		public class server_error : Statement {
			public bool Error { get; set; }
			public string Message { get; set; }
		}
	}

	/* ============ Display elements ============ */
	
	public enum LevelKind {
		LDM_DEFAULT,
		LDM_HELL,
		LDM_QUEST,
		LDM_MINES,
		LDM_SOKOBAN,
		LDM_ROGUE
	}
	public enum PauseReason {
		P_MESSAGE,
		P_MAP
	}

	public class MapDeltaCell {
		public int Effect { get; set; }
		public int BG { get; set; }
		public int Trap { get; set; }
		public int Obj { get; set; }
		public int Obj_Mn { get; set; }
		public int Mon { get; set; }
		public int MonFlags { get; set; }
		public int Branding { get; set; }
		public int Invis { get; set; }
		public int Visible { get; set; }
	}

	namespace Server {
		public class Display {
		}
		public class DisplayElement {
		}
	}
	namespace Server {
		public class delay_output : DisplayElement {
		}
		public class display_buffer : DisplayElement {
			public string Buf { get; set; }
			public bool TryMove { get; set; }
		}
		public class level_changed : DisplayElement {
			public LevelKind Kind { get; set; } // TODO: please fix protocol so that this works!
		}
		public class list_items : DisplayElement {
			public int ICount { get; set; }
			public bool Invent { get; set; } // is this a list of items in inventory?  Or on the floor?
			public List<ObjItem> Items { get; set; }
		}
		public class outrip : DisplayElement {
			public int Gold { get; set; }
			public EndClass How { get; set; }
			public int ICount { get; set; }
			public string KillBuf { get; set; }
			public string Name { get; set; }
			public bool Tombstone { get; set; }
			public int Year { get; set; }
			public List<MenuItem> Items { get; set; }
		}
		public class pause : DisplayElement {
			public PauseReason Reason { get; set; } // TODO: please adjust protocol
		}
		public class print_message : DisplayElement {
			public string Msg { get; set; }
			public int Turn { get; set; }
		}
		public class print_message_nonblocking : print_message {
		}
		public class raw_print : DisplayElement {
			public string Msg { get; set; }
		}
		public class update_screen : DisplayElement {
			public List<object> DBuf { get; set; }
			/* A map delta can be an integer 0 if nothing at all has changed.
			 * Otherwise it is a list of column deltas.
			 * A column delta of 0 means that column is empty, and 1 means it is unchanged since last time.
			 * Otherwise a column delta is a list of cell deltas.
			 * Again, 0 means empty, 1 means unchanged.
			 * Otherwise the cell delta is a simple list, as in MapDeltaCell.
			 */
			public int UV { get; set; }
			public int UX { get; set; }
		}
		public class update_status : DisplayElement {
			public int AC { get; set; }
			public int ALign { get; set; }
			public bool Can_Enhance { get; set; }
			public int Ch { get; set; }
			public int Co { get; set; }
			public char CoinSym { get; set; }
			public int Cur_MonNum { get; set; }
			public int Dx { get; set; }
			public int En { get; set; }
			public int EnMax { get; set; }
			public int Gold { get; set; }
			public int HP { get; set; }
			public int HPMax { get; set; }
			public int In { get; set; }
			public int Level { get; set; }
			public string Level_Desc { get; set; }
			public int Max_Rank_Sz { get; set; }
			public int MonNum { get; set; }
			public int Moves { get; set; }
			public int Nr_Items { get; set; }
			public string PlName { get; set; }
			public string Rank { get; set; }
			public int Score { get; set; }
			public int St { get; set; }
			public int St_Extra { get; set; }
			public List<string> StatusItems { get; set; }
			public int Wi { get; set; }
			public int X { get; set; }
			public int XP { get; set; }
			public int Y { get; set; }
			public int Z { get; set; }
		}
	}
}
}

